package com.alan.service.impl;

import com.alan.constants.SystemConstants;
import com.alan.domain.ResponseResult;
import com.alan.domain.entity.Article;
import com.alan.domain.entity.Category;
import com.alan.domain.vo.ArticleDetailVo;
import com.alan.domain.vo.ArticleListVo;
import com.alan.domain.vo.HotArticleVo;
import com.alan.domain.vo.PageVo;
import com.alan.mapper.ArticleMapper;
import com.alan.service.ArticleService;
import com.alan.service.CategoryService;
import com.alan.utils.BeanCopyUtils;
import com.alan.utils.RedisCache;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 文章表(Article)表服务实现类
 *
 * @author makejava
 * @since 2022-09-12 14:32:17
 */
@Service
public class ArticleServiceImpl
        extends ServiceImpl<ArticleMapper, Article>
        implements ArticleService {

    @Resource
    private CategoryService categoryService;

    @Resource
    private RedisCache redisCache;

    @Override
    public ResponseResult hotArticleList() {
        //查询热门文章 封装成ResponseResult返回
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //必须是正式文章
        queryWrapper.eq(Article::getStatus,0);
        //按照浏览量进行排序
        queryWrapper.orderByDesc(Article::getViewCount);
        //最多只查询10条
        Page<Article> page = new Page(1,10);
        page(page,queryWrapper);

        List<Article> articles = page.getRecords();
        //bean拷贝
        List<HotArticleVo> articleVos = new ArrayList<>();
        for (Article article : articles) {
            HotArticleVo vo = new HotArticleVo();
            BeanUtils.copyProperties(article,vo);
            articleVos.add(vo);
        }

        //从Redis中更新访问次数
        for (HotArticleVo articleVo : articleVos) {
            Integer viewCount = redisCache.
                    getCacheMapValue("Article:viewCount", articleVo.getId().toString());
            articleVo.setViewCount(Long.valueOf(viewCount));
        }

        return ResponseResult.okResult(articleVos);
    }

    /**
     * 查询文章列表：
     *           在首页和分类页面都需要查询文章列表。
     *           首页：查询所有的文章
     *           分类页面：查询对应分类下的文章
     *           要求：①只能查询正式发布的文章 ②置顶的文章要显示在最前面
     */
    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //判断有没有categoryId,有就查询Id，没有就查询所有
        queryWrapper.eq(Objects.nonNull(categoryId)&&categoryId>0,
                Article::getCategoryId,categoryId);
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);//正式发布的
        queryWrapper.orderByDesc(Article::getIsTop);//降序
        Page<Article> page = new Page<>(pageNum,pageSize);
        page(page, queryWrapper);
        List<Article> articles = page.getRecords();

        //查询categoryName
        for (Article article : articles) {
            String categoryName = categoryService.getById(article.getCategoryId()).getName();
            article.setCategoryName(categoryName);
        }

        //封装vo
        List<ArticleListVo> articleListVoList =
                BeanCopyUtils.copyBeanList(articles, ArticleListVo.class);
        PageVo pageVo = new PageVo(articleListVoList,page.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getArticleDetail(Integer id) {
        //根据id查询文章
        Article article = getById(id);
        //从redis中获取viewCount
        Integer viewCount = redisCache.
                getCacheMapValue("Article:viewCount", id.toString());
        article.setViewCount(viewCount.longValue());
        //转换成VO
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        //根据分类id查询分类名
        Long categoryId = articleDetailVo.getGetCategoryId();
        Category category = categoryService.getById(categoryId);
        if(category!=null){
            articleDetailVo.setCategoryName(category.getName());
        }
        //封装响应返回
        return ResponseResult.okResult(articleDetailVo);
    }

    @Override
    public ResponseResult updateViewCount(Long id) {
        //更新redis中对应 id的浏览量
        //先往Redis里存储，提高系统并发量
        redisCache.incrementCacheMapValue("Article:viewCount",id.toString(),1);
        return ResponseResult.okResult();
    }
}

